Itext7生成pdf最全api总结

您所在的位置:网站首页 java 生成api文档 Itext7生成pdf最全api总结

Itext7生成pdf最全api总结

2023-08-25 09:07| 来源: 网络整理| 查看: 265

Itext7生成pdf最全api总结

最近使用itext7生成pdf被折磨到崩溃,一是官方文档不全,网上文章基本都是基于老版本api的,已经完全不适用itext7版本;二是itext7的api和css很像,使用java写css很让人崩溃。把我用到的做一个总结。

显示中文

itext7在使用默认字体显示中文的时候,由于默认字库不支持中文,生成的pdf中的中文会显示空白,要解决这个问题需要自己引入字体。

下载一个中文字体,我这里用的是SourceHanSansCN.ttf(只用过ttf文件,不知道是否支持其他字体文件的格式)

加载中文字体

InputStream inputStream = new FileInputStream(new File("SourceHanSansCN.ttf")); //第三个参数为embedded,是否为内置字体,这里是自己提供的所以传false PdfFont font = PdfFontFactory.createFont(IOUtils.toByteArray(inputStream), PdfEncodings.IDENTITY_H, false);

设置字体

//默认是A4纸大小 Document document = new Document(pdfDocument, new PageSize()); document.setFont(font); 分辨率

大部分情况下,生成的pdf是有打印需求的,打印就涉及到pdf分辨率的问题。在itext中除了插入的图片外其他都是矢量图所以不必担心分辨率的问题,只需要保证插入图片的分辨率即可,在itext中生成图片的分辨率默认是72dpi,这里是需要做一些处理的,如下:

int defaultDpi = 72; int targetDpi = 300; Image test = new Image(ImageDataFactory.create("test.jpg")); test.scale(defaultDpi/targetDpi, defaultDpi/targetDpi); 布局

Itext坐标系如下图,当使用绝对布局的时候需要计算元素距离左侧和下侧的长度,当使用相对布局的时候,元素则是自上往下排列。

坐标原点图

绝对布局 setFixedPosition(float left, float bottom, float width) 相对布局

使用相对布局时,不需要setFixedPosition,只需要设置距离上下左右的长度即可,这里感觉有点类似于css了。

setMarginLeft(float value); setMarginRight(float value); setMarginBottom(float value); setMarginTop(float value); setMargin(float commonMargin); 自动分页+生成页码

在使用绝对布局的时候,大部分情况下页面内容是固定大小的,位置也是固定的,分页也需要自己写代码来进行控制。但是如果pdf的内容不是固定的,这时候如果使用绝对布局就不是那么的灵活了,还需要自己计算元素的高度也设置绝对位置,这个时候我们选择使用相对布局则会更合适、简单一些。代码如下:

class PageEventHandler implements IEventHandler { private Document document; private PdfFont font; //由于需要统一和汉字的字体,所以加了一个pdffont参数,没有此需求的可以不加 public PageEventHandler(Document document, PdfFont font){ this.document = document; this.font = font; } @Override public void handleEvent(Event event) { PdfDocumentEvent pdfEvent = (PdfDocumentEvent) event; PdfPage page = pdfEvent.getPage(); PdfDocument pdfDoc = pdfEvent.getDocument(); //获取当前页码 int pageNumber = pdfDoc.getPageNumber(page); PdfCanvas pdfCanvas = new PdfCanvas( page.newContentStreamBefore(), page.getResources(), pdfDoc); //在距离上个元素50的距离处写页码 this.document.setTopMargin(50f); pdfCanvas.beginText() .setFontAndSize(this.font, 32) //在页面一般宽的地方写上当前页面,由于字体定位的原点也在左下角,所以这里x轴减掉了页码宽度的一半,确保页码是写在中间的位置 //y轴是距离底部20px .moveText(PageSize.A4.getWidth()/2-32/2, 20f) .showText(String.valueOf(pageNumber)) .endText(); pdfCanvas.release(); } } //使用 pdfDocument.addEventHandler(PdfDocumentEvent.START_PAGE, new PageEventHandler(document, font)); 常用组件 Table //不指定table每一列的宽度,根据列的内容自适应 public Table(int numColumns); //指定每一列的宽度 public Table(float[] pointColumnWidths); //向table里面添加单元格,默认是横着加,达到指定列数后,自动换行 public Table addCell(Cell cell); //设置table或cell的边框,这里需要注意,如果不想显示边框,需要在每一个cell中都设置border为none,只设置table的边框还是会显示边框的 public T setBorder(Border border); //无边框 cell.setBorder(Border.NO_BORDER); //实线边框 cell.setBorder(new SolidBorder(1)); //虚线边框 cell.setBorder(new DashedBorder(1)); //四个都是圆角 cell.setBorderRadius(new BorderRadius(10f)); //圆角-右下角 cell.setBorderBottomRightRadius(new BorderRadius(10f)); //圆角-左下角 cell.setBorderBottomLeftRadius(new BorderRadius(10f)); //圆角-右上角 cell.setBorderTopRightRadius(new BorderRadius(10f)); //圆角-左上角 cell.setBorderTopLeftRadius(new BorderRadius(10f)); //关于圆角这一部分,table中的圆角,似乎设置了并不能生效,不过可以通过将外围的table的border设置为none,内部的cell设置边框实现

例子

用table实现一个进度条

思路:外层一个一行一列的table,内部cell再套一个一行一列的table作为实际的进度,根据百分比计算内部table的宽度

代码:

//percent这里传的是小数 public void processBar(Document document, float width, float percent){ float processWidth = width * percent; DeviceRgb processColor = new DeviceRgb(11,11,11);//随便写个颜色吧 DeviceRgb processBgColor = new DeviceRgb(101,11,11);//随便写个颜色吧 Table table = new Table(new float[]{width}).setMargin(0).setPadding(0);//把不必要的空隙都扼杀在摇篮里 Table processTable = new Table(new float[]{processWidth}).setMargin(0).setPadding(0); processTable.addCell(new Cell().setBorder(Border.NO_BORDER) .setMargin(0).setPadding(0).setBackgroundColor(processColor)); table.addCell(new Cell().setBorder(Border.NO_BORDER).setBackgroundColor(processBgColor) .setMargin(0).setPadding(0).setBorder(Border.NO_BORDER).add(processTable)); } Paragraph

paragraph应该是最经常使用的一个类了,pdf中写文字都会用到这个类。

Paragraph para = new Paragraph("我是一个paragraph") .setFontSize(14)//设置字体大小 .setBold()//设置文字为粗体 .setFontColor(new DeviceRgb(0,0,0))//设置字体颜色 .setTextAlignment(TextAlignment.CENTER)//文字水平居中 .setFixedLeading(14);//类似于css中的行高

有的时候会有一些需求是,同一段落的一段文字中有部分文字需要设置成别的颜色或样式样式,这时候可以Text来处理,如下:

//这种处理方式不能处理加粗的问题,如果想要加粗的文字正好在段落的中间,但是如果设置为粗体会导致整段文字都变成粗体(斜体是同理的) para.add(new Text("我想与众不同").setFontSize("20").setFontColor(new DeviceRgb(255,255,255))); Image //图片分辨率问题见上面分辨率部分 Image image = new Image(ImageDataFactory.create("/home/test.jpg")); 保存 写磁盘 ByteArrayOutputStream bos = new ByteArrayOutputStream(); PdfWriter writer = new PdfWriter(bos); PdfDocument pdfDocument = new PdfDocument(writer); Document document = new Document(pdfDocument, new PageSize()); //各种乱写乱画 byte[] fileBytes = bos.toByteArray(); FileOutputStream fos = new FileOutputStream("要保存的路径"); fos.write(fileBytes); fos.flush(); bos.close(); fos.close(); 返回文件流 ByteArrayOutputStream bos = new ByteArrayOutputStream(); PdfWriter writer = new PdfWriter(bos); PdfDocument pdfDocument = new PdfDocument(writer); Document document = new Document(pdfDocument, new PageSize()); //各种乱写乱画 byte[] fileBytes = bos.toByteArray(); return fileBytes;


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3